﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace crdmcgui
{
    [Serializable]
    public class RulesetGroup : DataManagerContainer
    {
        #region Properties

        public override string Name
        {
            get
            {
                if (string.IsNullOrEmpty(_name))
                {
                    return "Unnamed Group";
                }
                else
                {
                    return _name;
                }
            }
            set
            {
                if (value == "Unnamed Group")
                    _name = "";
                else
                    _name = value;
            }
        }
        public override string Comment { get; set; }

        #endregion

        #region Initilization

        public RulesetGroup()
        {
        }

        public RulesetGroup(string[] strArrayGroup)
            :this()
        {
            Parse(strArrayGroup);
        }
                
        #endregion

        #region Non-Base

        /// <summary>
        /// Parses the Group from header point until group end is identified
        /// </summary>
        /// <param name="strGroupStrings"></param>
        /// <returns>The line number of the end of the group</returns>
        public int Parse(string[] strGroupStrings, int nGroupStartLine)
        {
            int counter = nGroupStartLine;
            string[] tmpNameAndComment = new string[] { };

            while (counter < strGroupStrings.Length && IdentifyLineType(strGroupStrings[counter]) != LineParseType.GroupEndLine)
            {
                switch (IdentifyLineType(strGroupStrings[counter]))
                {
                    case LineParseType.GroupStartLine:
                        counter = ParseGroup(strGroupStrings, counter, this);
                        break;
                    case LineParseType.RulesetNameLine:
                        tmpNameAndComment = GetNameAndComment(strGroupStrings[counter]);
                        break;
                    case LineParseType.RulesetLine:
                        Ruleset tmpRuleset = new Ruleset(strGroupStrings[counter]);
                        if (tmpNameAndComment.Length > 0) tmpRuleset.Name = tmpNameAndComment[0];
                        if (tmpNameAndComment.Length > 1) tmpRuleset.Comment = tmpNameAndComment[1];
                        AddRuleset(tmpRuleset);
                        break;
                    default:
                        break;
                }
                counter++;
            }
            return counter;
        }

        private void Parse(string[] strGroupStrings)
        {
            int counter = 1;
            string[] tmpNameAndComment = GetNameAndComment(strGroupStrings[counter]);
            if (tmpNameAndComment.Length > 0) Name = tmpNameAndComment[0].Trim(); ;
            if (tmpNameAndComment.Length > 1) Comment = tmpNameAndComment[1].Trim();

            counter++;
            while (counter < strGroupStrings.Length && IdentifyLineType(strGroupStrings[counter]) != LineParseType.GroupEndLine)
            {
                switch (IdentifyLineType(strGroupStrings[counter]))
                {
                    case LineParseType.GroupStartLine:
                        counter = ParseGroup(strGroupStrings, counter, this);
                        break;
                    case LineParseType.RulesetNameLine:
                        tmpNameAndComment = GetNameAndComment(strGroupStrings[counter]);
                        break;
                    case LineParseType.RulesetLine:
                        Ruleset tmpRuleset = new Ruleset(strGroupStrings[counter]);
                        if (tmpNameAndComment.Length > 0) tmpRuleset.Name = tmpNameAndComment[0];
                        if (tmpNameAndComment.Length > 1) tmpRuleset.Comment = tmpNameAndComment[1];
                        AddRuleset(tmpRuleset);
                        break;
                    default:
                        break;
                }
                counter++;
            }
        }


        public override string[] Compile()
        {
            List<string> CompiledRulesetGroup = new List<string>();


            string tmpString = Global.GroupHeader + Name;
            CompiledRulesetGroup.Add(Global.Divider);
            if (!string.IsNullOrEmpty(Comment))
            {
                tmpString += " " + Global.CommentHeader + Comment;
            }
            CompiledRulesetGroup.Add(tmpString);
            CompiledRulesetGroup.Add(Global.Divider);
            for (int i = 0; i < GroupCount; i++)
            {
                CompiledRulesetGroup.AddRange(Groups[i].Compile());
            }

            for (int i = 0; i < RulesetCount; i++)
            {
                CompiledRulesetGroup.AddRange(Rulesets[i].Compile());
            }
            CompiledRulesetGroup.Add(Global.EndOfGroup + " " + Name);
            CompiledRulesetGroup.Add(Global.Divider);

            return CompiledRulesetGroup.ToArray();
        }

        #endregion


        public RulesetGroup Clone()
        {
            RulesetGroup tmp = new RulesetGroup();
            tmp.Name = this.Name;
            tmp.Comment = this.Comment;

            foreach (RulesetGroup item in Groups)
            {
                tmp.Groups.Add(item.Clone());
            }

            foreach (Ruleset item in Rulesets)
            {
                tmp.Rulesets.Add(item.Clone());
            }
            return tmp;
        }
    }
}
